package com.thf.service.impl;


import com.thf.dao.EsProductRepository;
import com.thf.dao.ProductDao;
import com.thf.model.ResultData;
import com.thf.model.product.ProductModel;
import com.thf.service.ProductService;
import com.thf.util.ResultTool;
import com.thf.util.Tool;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

@Service
public class ProductServiceImpl implements ProductService {
    @Resource
    private ProductDao productDao;
    @Resource
    private EsProductRepository productRepository;
    @Resource
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

//    public static void main(String[] args) {
//        BigDecimal price= new BigDecimal("6000");
//        System.out.println(price);
//    }
    @Override
    public ResultData productFindAll(Integer startPage,Integer pageSize, Map map) {
//        ProductModel productModel = new ProductModel();
//        productModel.setProductName(Tool.jsonToString(map.get("name")));
//        productModel.setCreateTime(Tool.jsonToString(map.get("start")));
//        productModel.setUpdateTime(Tool.jsonToString(map.get("end")));
//        BigDecimal price= new BigDecimal(Tool.StringToNotNull((String)map.get("price")));
//        productModel.setPrice(price);
//        productModel.setProductType(Tool.jsonToString(map.get("type")));
//        productModel.setEnable(Tool.jsonToString(map.get("enable")));
//        List<ProductModel> list = null;
//            list = productDao.findAll(pageModel, productModel);
//        if (list == null) {
//            return new ResultData(ResultTool.CODE_ERROR, ResultTool.CODE_ERROR_MSG);
//        }
//        return new ResultData(ResultTool.CODE_SUCCES, ResultTool.CODE_SUCCES_MSG, list);
        SearchHits<ProductModel> searchHits = null ;
                BoolQueryBuilder builder = QueryBuilders.boolQuery();
        BigDecimal price= new BigDecimal(Tool.StringToNotNull((String)map.get("price")));
        if (StringUtils.isNotBlank((String) map.get("name"))){
            builder.must(QueryBuilders.matchQuery("productName", map.get("name")));
        }
        if (StringUtils.isNotBlank((String) map.get("type"))){
            builder.must(QueryBuilders.matchQuery("productType", map.get("type")));
        }
        if(price.compareTo(BigDecimal.ZERO)!=0){
            builder.must(QueryBuilders.rangeQuery("price").lt(price));
        }
        if(StringUtils.isNotBlank((String) map.get("enable"))){
            builder.must(QueryBuilders.matchQuery("enable", map.get("enable")));
        }
        if(StringUtils.isNotEmpty((String) map.get("start")) && StringUtils.isEmpty((String) map.get("end"))){
            builder.must(QueryBuilders.rangeQuery("shelfTime").gte(map.get("start")));
        }
        if(StringUtils.isEmpty((String) map.get("start")) && StringUtils.isNotEmpty((String) map.get("end"))){
            builder.must(QueryBuilders.rangeQuery("shelfTime").lte(map.get("end")));
        }
        if(StringUtils.isNotEmpty((String) map.get("start")) && StringUtils.isNotEmpty((String) map.get("end"))){
            builder.must(QueryBuilders.rangeQuery("shelfTime").from(map.get("start")).to(map.get("end")));
        }
        Pageable pageable = PageRequest.of(startPage,pageSize, Sort.by(Sort.Direction.DESC,"id"));
//        Page<ProductModel> search = productRepository.search(builder, pageable);
        HighlightBuilder.Field field = new HighlightBuilder.Field("productName")
                .preTags("<font color='red'>")
                .postTags("</font>");
        NativeSearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(builder)
                .withHighlightFields(field)
                .withPageable(pageable)
                .build();
        searchHits = elasticsearchRestTemplate.search(query, ProductModel.class);
        List<SearchHit<ProductModel>> searchHitList = searchHits.getSearchHits();
//        List<ProductModel> productModelList = new ArrayList(searchHitList.size());
        List<ProductModel> productModelList = new ArrayList(searchHitList.size());
        for (SearchHit<ProductModel> searchHit : searchHitList) {
            ProductModel productModel = searchHit.getContent();
            if(searchHit.getHighlightFields().size()>0){
                String highlightName = searchHit.getHighlightField("productName").get(0);
                productModel.setProductName(highlightName);
            }
            productModelList.add(productModel);
        }
        HashMap hashMap = new HashMap();
        if (searchHitList == null) {
            return new ResultData(ResultTool.CODE_ERROR, ResultTool.CODE_ERROR_MSG);
        }
        hashMap.put("list",productModelList);
        hashMap.put("count",searchHits.getTotalHits());
        return new ResultData(ResultTool.CODE_SUCCES, ResultTool.CODE_SUCCES_MSG, hashMap);
    }

    @Override
    public Integer getCount(Map map) {
//        ProductModel productModel = new ProductModel();
//        productModel.setProductName(Tool.jsonToString(map.get("name")));
//        productModel.setCreateTime(Tool.jsonToString(map.get("start")));
//        productModel.setUpdateTime(Tool.jsonToString(map.get("end")));
//        BigDecimal price= new BigDecimal(Tool.StringToNotNull((String)map.get("price")));
//        productModel.setPrice(price);
//        productModel.setProductType(Tool.jsonToString(map.get("type")));
//        productModel.setEnable(Tool.jsonToString(map.get("enable")));
//        Integer count = null ;
//        if(productModel != null){
//            count = productDao.getCount(productModel);
//        }
        BoolQueryBuilder builder = QueryBuilders.boolQuery();
        BigDecimal price= new BigDecimal(Tool.StringToNotNull((String)map.get("price")));
        if (StringUtils.isNotBlank((String) map.get("name"))){
            builder.must(QueryBuilders.matchQuery("productName", map.get("name")));
        }
        if (StringUtils.isNotBlank((String) map.get("type"))){
            builder.must(QueryBuilders.matchQuery("productType", map.get("type")));
        }
        if(price.compareTo(BigDecimal.ZERO)!=0){
            builder.must(QueryBuilders.rangeQuery("price").lt(price));
        }
        if(StringUtils.isNotBlank((String) map.get("enable"))){
            builder.must(QueryBuilders.matchQuery("enable", map.get("enable")));
        }
        if(StringUtils.isNotEmpty((String) map.get("start")) && StringUtils.isEmpty((String) map.get("end"))){
            builder.must(QueryBuilders.rangeQuery("shelfTime").gte(map.get("start")));
        }
        if(StringUtils.isEmpty((String) map.get("start")) && StringUtils.isNotEmpty((String) map.get("end"))){
            builder.must(QueryBuilders.rangeQuery("shelfTime").lte(map.get("end")));
        }
        if(StringUtils.isNotEmpty((String) map.get("start")) && StringUtils.isNotEmpty((String) map.get("end"))){
            builder.must(QueryBuilders.rangeQuery("shelfTime").from(map.get("start")).to(map.get("end")));
        }
        NativeSearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(builder)
                .build();
        SearchHits<ProductModel> searchHits = elasticsearchRestTemplate.search(query, ProductModel.class);
        long totalHits = searchHits.getTotalHits();
        System.out.println("产品数量========>"+totalHits);
        return (int) searchHits.getTotalHits();
    }

    @Override
    public ResultData add(Map map) {
        ProductModel productModel = new ProductModel();
        productModel.setProductName(Tool.jsonToString(map.get("name")));
        BigDecimal price= new BigDecimal(Tool.StringToNotNull((String)map.get("price")));
        BigDecimal normalPrice= new BigDecimal(Tool.StringToNotNull((String)map.get("normalPrice")));
        productModel.setPrice(price);
        productModel.setNormalPrice(normalPrice);
        productModel.setProductType(Tool.jsonToString(map.get("type")));
        productModel.setEnable(Tool.jsonToString(map.get("enable")));
        productModel.setImg(Tool.jsonToString(map.get("url")));
        productModel.setContent(Tool.jsonToString(map.get("describe")));
        productModel.setCreateTime(Tool.dateToString(new Date()));
        Integer count = null ;
        if(productModel!=null){
            count = productDao.add(productModel);
//            System.out.println("主键id========>"+productModel.getId());
            productRepository.save(productModel);
        }
        if(count ==0){
            return new ResultData(ResultTool.CODE_ERROR, ResultTool.CODE_ADD_ERROR_MSG);
        }
        return new ResultData(ResultTool.CODE_SUCCES, ResultTool.CODE_ADD_SUCCES_MSG,count);
    }

    @Override
    public ResultData getProductById(Integer pid) {
        ProductModel productModel = null;
        if(pid != null){
//            productModel = productDao.getProductById(pid);
            productModel = productRepository.findById(pid).get();
        }
        if(productModel == null){
            return new ResultData(ResultTool.CODE_ERROR, ResultTool.CODE_PRODUCT_ID_ERROR_MSG);
        }
        return new ResultData(ResultTool.CODE_SUCCES, ResultTool.CODE_PRODUCT_ID_SUCCES_MSG,productModel);
    }

    @Override
    public ResultData update(Map map) {
        ProductModel productModel = new ProductModel();
        productModel.setProductName(Tool.jsonToString(map.get("name")));
        BigDecimal price= new BigDecimal(Tool.StringToNotNull((String)map.get("price")));
        BigDecimal normalPrice= new BigDecimal(Tool.StringToNotNull((String)map.get("normalPrice")));
        productModel.setPrice(price);
        productModel.setNormalPrice(normalPrice);
        productModel.setProductType(Tool.jsonToString(map.get("type")));
        productModel.setEnable(Tool.jsonToString(map.get("enable")));
        productModel.setImg(Tool.jsonToString(map.get("url")));
        productModel.setContent(Tool.jsonToString(map.get("describe")));
        productModel.setId((Integer) map.get("id"));
        productModel.setUpdateTime(Tool.dateToString(new Date()));
        Integer count = null ;
        if(productModel!=null){
            count = productDao.update(productModel);
            productRepository.save(productModel);
        }
        if(count ==0){
            return new ResultData(ResultTool.CODE_ERROR, ResultTool.CODE_ADD_ERROR_MSG);
        }
        return new ResultData(ResultTool.CODE_SUCCES, ResultTool.CODE_ADD_SUCCES_MSG,count);
    }

    @Override
    public ResultData delete(Integer pid) {
        Integer count = null ;
        if(pid != null){
            count = productDao.delete(pid);
            productRepository.deleteById(pid);
        }
        if(count ==0){
            return new ResultData(ResultTool.CODE_ERROR, ResultTool.CODE_DEL_ERROR_MSG);
        }
        return new ResultData(ResultTool.CODE_SUCCES, ResultTool.CODE_DEL_SUCCES_MSG,count);
    }
}
